--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, Xmake Open Source Community.
--
-- @author      ruki
-- @file        proto.lua
--

-- imports
import("core.base.option")
import("lib.detect.find_tool")
import("core.project.depend")
import("utils.progress")
import("private.utils.batchcmds")

-- get flatc
function _get_flatc(target, sourcekind)

    -- find flatc
    local envs = os.joinenvs(target:pkgenvs(), os.getenvs())
    local flatc = target:data("flatbuffers.flatc")
    if not flatc then
        flatc = find_tool("flatc", {envs = envs})
        if flatc and flatc.program then
            target:data_set("flatbuffers.flatc", flatc.program)
        end
    end

    -- get flatc
    return assert(target:data("flatbuffers.flatc"), "flatc not found!")
end

-- we need to add some configs to export includedirs to other targets in on_load
-- @see https://github.com/xmake-io/xmake/issues/2256
function load(target, sourcekind)

    local sourcebatch = target:sourcebatches()[sourcekind == "cxx" and "flatbuffers.cpp" or "flatbuffers.c"]
    for _, sourcefile_flat in ipairs(sourcebatch and sourcebatch.sourcefiles) do
        local prefixdir
        local autogendir
        local public
        local fileconfig = target:fileconfig(sourcefile_flat)
        if fileconfig then
            public = fileconfig.flat_public
            prefixdir = fileconfig.flat_rootdir
            autogendir = fileconfig.flat_autogendir
        end
        local rootdir = autogendir and autogendir or path.join(target:autogendir(), "rules", "flatbuffers")
        local filename = path.basename(sourcefile_flat) .. "_generated.h"
        local sourcefile_cx = target:autogenfile(sourcefile_flat, {rootdir = rootdir, filename = filename})
        local sourcefile_dir = prefixdir and path.join(rootdir, prefixdir) or path.directory(sourcefile_cx)

        -- add includedirs
        target:add("includedirs", sourcefile_dir, {public = public})
    end
end

function buildcmd_pfile(target, batchcmds, sourcefile_flat, sourcekind, opt)

    -- get flatc
    local flatc = _get_flatc(target, sourcekind)

    -- get c/c++ source file for flatbuffers
    local prefixdir
    local autogendir
    local public
    local flat_flags
    local fileconfig = target:fileconfig(sourcefile_flat)
    if fileconfig then
            public = fileconfig.flat_public
            prefixdir = fileconfig.flat_rootdir
            autogendir = fileconfig.flat_autogendir
            flat_flags = fileconfig.flat_flags
    end
    local rootdir = autogendir and autogendir or path.join(target:autogendir(), "rules", "flatbuffers")
    local filename = path.basename(sourcefile_flat) .. "_generated.h"
    local includefile = target:autogenfile(sourcefile_flat, {rootdir = rootdir, filename = filename})
    local sourcefile_dir = prefixdir and path.join(rootdir, prefixdir) or path.directory(includefile)

    local flatc_args = {
        "-I",
        path(prefixdir and prefixdir or path.directory(sourcefile_flat)),
        "-o",
        path(sourcefile_dir),
        path(sourcefile_flat)
    }

    if sourcekind == "cxx" then
        table.insert(flatc_args,"--cpp")
    end

    if flat_flags then
        table.join2(flatc_args, flat_flags)
    end

    -- add commands
    batchcmds:mkdir(sourcefile_dir)
    batchcmds:show_progress(
        opt.progress,
        "${color.build.object}compiling.proto.%s %s",
        "c++",
        sourcefile_flat
    )
    batchcmds:vrunv(flatc, flatc_args)

    -- add deps
    local depvalues = {flatc,flatc_args}
    local depmtime = os.mtime(includefile)
    batchcmds:add_depfiles(sourcefile_flat)
    batchcmds:add_depvalues(depvalues)
    batchcmds:set_depmtime(depmtime)
    batchcmds:set_depcache(target:dependfile(includefile))
end
